package com.authine.cloudpivot.ext.controller.InOutStroage;

import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.Utils.Utils;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 生產入库
 **/
@RestController
@RequestMapping("/public/ProductIntoStroageController")
@Slf4j
public class ProductIntoStroageController extends BaseController {
    @Autowired
    CloudSqlService sqlService;

    /**
     * 生產入库  审批流完成后 数据写到-库存/预库存 基础表
     * 入库日期<=当前日期 库存基础表
     * 入库日期>当前日期 预库存基础表
     */
    @RequestMapping("finish")
    public void finish(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.ProductInto, bizId);

        //Sheet1665369415055  子表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get("Sheet1665369415056");
        String type = (String) bizObject.get("type");


        Date nowTime = Calendar.getInstance().getTime();
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

//        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        String approval = "";
        for (Map<String, Object> map : list) {

            Date entryDate = (Date) map.get("entryDate");//入库日期
            //两个日期相等，返回0
            //entryDate < nowTime，返回负值
            //entryDate > nowTime，返回正值
            int i = entryDate.compareTo(nowTime);
            BigDecimal zero = BigDecimal.valueOf(0);
            BigDecimal quantityFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal quantity = BigDecimal.valueOf(0);
            BigDecimal auxiliaryQuantityFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal auxiliaryQuantity = BigDecimal.valueOf(0);
            BigDecimal amountFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal amount = BigDecimal.valueOf(0);
            BigDecimal actualAmountFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal actualAmount = BigDecimal.valueOf(0);
            BigDecimal taxFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal tax = BigDecimal.valueOf(0);
            BigDecimal totalFromSubSheet = BigDecimal.valueOf(0);
            BigDecimal total = BigDecimal.valueOf(0);

            BigDecimal planInFromSubSheet= BigDecimal.valueOf(0);
            BigDecimal planIn = BigDecimal.valueOf(0);
            BigDecimal planOutFromSubSheet= BigDecimal.valueOf(0);
            BigDecimal planOut = BigDecimal.valueOf(0);
            BigDecimal planFromSubSheet= BigDecimal.valueOf(0);
            BigDecimal plan = BigDecimal.valueOf(0);


            try {

                if (i <= 0) {
                    //说明入库日期在今天及之前。（过去已入库）
                    Map<String, Object> mapFromBase = existsBizObject(map, bizObject);//mapFromBase是基础表的数据
                    Map<String, Object> data = new HashMap<>();

                    if (mapFromBase == null || mapFromBase.size() == 0) {
                        //此时代表通过查询条件，在基础表的查询结果为空
                        //不累加也不累减，直接将子表的数据插入基础表
                        data = fileInfoBaseMap(map, now, approval, bizObject);

                    }

                    String idFromBase = (String) mapFromBase.get("id");
                    if ("生产入库".equals(type) && (mapFromBase != null & mapFromBase.size() > 0)) {
                        data.put("id", idFromBase);

//                    BigDecimal quantity1 = (BigDecimal) mapFromBase.get("quantity");
//                    BigDecimal quantity2 = (BigDecimal) map.get("quantity");
//                    BigDecimal subtract = quantity1.subtract(quantity2);

                        //执行累加逻辑
                        //数量 quantity
                        quantityFromSubSheet = (BigDecimal) mapFromBase.get("quantity");//基础表的【数量】
                        quantity = zero.add((BigDecimal) map.get("quantity"));//子表表的【数量】
                        //辅助数量 auxiliaryQuantity
                        auxiliaryQuantityFromSubSheet = (BigDecimal) mapFromBase.get("auxiliaryQuantity");//基础表的【辅助数量】
                        auxiliaryQuantity = zero.add((BigDecimal) map.get("auxiliaryQuantity"));//子表表的【辅助数量】
                        //金额 amount
                        amountFromSubSheet = (BigDecimal) mapFromBase.get("amount");//基础表的【金额】
                        amount = zero.add((BigDecimal) map.get("amount"));//子表表的【金额】
                        //现值 actualAmount
                        actualAmountFromSubSheet = (BigDecimal) mapFromBase.get("actualAmount");//基础表的【现值】
                        actualAmount = zero.add((BigDecimal) map.get("actualAmount"));//子表表的【现值】
                        //税额 tax
                        taxFromSubSheet = (BigDecimal) mapFromBase.get("tax");//基础表的【税额】
                        tax = zero.add((BigDecimal) map.get("tax"));//子表表的【税额】
                        //价税合计 total
                        totalFromSubSheet = (BigDecimal) mapFromBase.get("total");//基础表的【价税合计】
                        total = zero.add((BigDecimal) map.get("total"));//子表表的【价税合计】


                    }

                    if (mapFromBase != null & mapFromBase.size() > 0) {
                        data.put("quantity", quantityFromSubSheet.add(quantity).toString());//数量
                        data.put("auxiliaryQuantity", auxiliaryQuantityFromSubSheet.add(auxiliaryQuantity).toString());//辅助数量
                        data.put("amount", amountFromSubSheet.add(amount).toString());//金额
                        data.put("actualAmount", actualAmountFromSubSheet.add(actualAmount).toString());//现值
                        data.put("tax", taxFromSubSheet.add(tax).toString());//税额
                        data.put("total", totalFromSubSheet.add(total).toString());//价税合计

//                        //计划入 planIn
//                        planInFromSubSheet = (BigDecimal) mapFromBase.get("planIn");//基础表的【计划入】
//                        //计划出 planOut
//                        planOutFromSubSheet = (BigDecimal) mapFromBase.get("planOut");//基础表的【计划入】
//                        //计划库存 plan
//                        planFromSubSheet = (BigDecimal) mapFromBase.get("plan");//基础表的【计划入】
//
//
//
//                        plan=(planInFromSubSheet.subtract(planOutFromSubSheet)).add(quantityFromSubSheet.add(quantity));
//                        data.put("plan",plan.toString());
                    }


                    //将子表中数据处理，随后更新至【库存 基础表】
                    BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.warehouse, data, false);
                    model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                    String id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                    log.info("基础表-庫存基础更新成功:{}", id);
                }
                if (i > 0) {
                    //说明入库日期在今天之后。（未来入库）
                    Map<String, Object> data = new HashMap<>();
                    data = fileInfoPreBaseMap(map, now, approval, bizObject);
                    data.put("entryDate", map.get("entryDate"));
                    //将子表中数据处理，随后更新至【库存 基础表】
                    BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.warehousePre, data, false);
                    model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                    String id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                    log.info("基础表-人员信息基础更新成功:{}", id);


                }


                //调用存储过程


            } catch (Exception e) {
//                String matCode = (String) map.get("code");
//                String storageSpace = (String) map.get("storageSpace");
//
//                log.info("基础表-人员信息基础操作失败 matCode={},storageSpace={}", matCode, storageSpace);
//                log.info(e.getMessage(), e);
            }

        }
    }


    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity12";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            final String finalActivityCode2 = "Activity9";
            Optional<WorkItemModel> second = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode2)).findFirst();
            if (second.isPresent()) {
                WorkItemModel workItemModel = second.get();
                participant = workItemModel.getParticipant();
            }
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 从主表的子表中获取数据，作为基础表的查询条件
     *
     * @param data      审批表子表数据
     * @param bizObject 审批表主表数据
     * @return
     */
    private Map<String, Object> existsBizObject(Map data, BizObjectCreatedModel bizObject) {

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.warehouse);

        String companyNumber = (String) bizObject.get("companyNumber");//获取主表数据 公司代码
        String supplierCodeTxt = MapUtils.getString(bizObject.getData(),"supplierCode","");//获取主表数据 供应商代码
        String supplierCode = StringUtils.isBlank(supplierCodeTxt) ? "is null" : "= '"+supplierCodeTxt+"'";
        String supplierNameTxt = MapUtils.getString(bizObject.getData(),"supplierName","");//获取主表数据 供应商名称
        String supplierName = StringUtils.isBlank(supplierNameTxt) ? "is null" : "= '"+supplierNameTxt+"'";
        String currencyHidden = (String) bizObject.get("currencyHidden");//获取主表数据 币别
        //带小数
        BigDecimal exchangeRate = (BigDecimal) bizObject.getData().get("exchangeRate");//获取主表数据 汇率

//        String exchangeRateStr = data.get("exchangeRate") == null ? "0" : data.get("exchangeRate").toString();//获取子表数据 汇率
//        BigDecimal exchangeRate = "0E-8".equals(exchangeRateStr) ? new BigDecimal("0") : new BigDecimal(exchangeRateStr).setScale(6, BigDecimal.ROUND_HALF_UP);

        String warehouseNumberHidden = (String) bizObject.get("warehouseNumberHidden");//获取主表数据 仓库编码

        //TODO: 完善查询条件
        //data是审批表子表的每行数据，获取查询条件
        String abstractTxt = MapUtils.getString(data,"abstract","");//获取子表数据 摘要
        String abstractT = StringUtils.isBlank(abstractTxt) ? "(abstract is null or abstract = '')" : "   replace(replace('"+abstractTxt+"','/','') ,'\\\\','')  = replace(replace( abstract ,'/','' ),'\\\\','') ";
        String storageSpaceTxt = MapUtils.getString(data,"storageSpace","");//获取子表数据 仓位
        String storageSpace = StringUtils.isBlank(storageSpaceTxt) ? "is null" : "= '"+storageSpaceTxt+"'";

        String code = (String) data.get("code");//获取子表数据 编码
        String modelTxt = MapUtils.getString(data,"model","");//获取子表数据 型号
        String model = StringUtils.isBlank(modelTxt) ? "(model is null or model = '')" : "   replace(replace('"+modelTxt+"','/','') ,'\\\\','')  = replace(replace( model ,'/','' ),'\\\\','') ";



        String batchTxt = MapUtils.getString(data,"batch","");//获取子表数据 批次
        String batch = StringUtils.isBlank(batchTxt) ? "is null" : "= '"+batchTxt+"'";

        Date productionDate = (Date) data.get("productionDate");//获取子表数据 生产日期
        String productionDateString = ObjectUtils.isEmpty(productionDate) ? "is null" : "= '"+productionDate.toString()+"'";

        Date expiryDate = (Date) data.get("expiryDate");//获取子表数据 到期日期
        String expiryDateString = ObjectUtils.isEmpty(expiryDate) ? "is null" : "= '"+expiryDate.toString()+"'";

        String measuringUnit = (String) data.get("measuringUnit");//获取子表数据 计量单位
        String auxiliaryUnitTxt = MapUtils.getString(data,"auxiliaryUnit","");//获取子表数据 辅助计量单位
        String auxiliaryUnit = StringUtils.isBlank(auxiliaryUnitTxt) ? "is null" : "= '"+auxiliaryUnitTxt+"'";

//        String unitPriceStr = data.get("unitPrice") == null ? "0" : data.get("unitPrice").toString();//获取子表数据 单价
//        BigDecimal unitPrice = "0E-8".equals(unitPriceStr) ? new BigDecimal("0") : new BigDecimal(unitPriceStr).setScale(6, BigDecimal.ROUND_HALF_UP);
//
//        String actualPriceStr = data.get("actualPrice") == null ? "0" : data.get("actualPrice").toString();//获取子表数据 现价
//        BigDecimal actualPrice = "0E-8".equals(actualPriceStr) ? new BigDecimal("0") : new BigDecimal(actualPriceStr).setScale(6, BigDecimal.ROUND_HALF_UP);


        //第一个入参data.get("数值类型的数据项编码")，第二个入参sql查询字段
        //例如传入data.get("unitPrice"), "price"，获得的返回值是：price = '1' 或者 price is null
        String priceSql = Utils.getPrettyNumberSqlString(data.get("unitPrice"), "price");//获取子表数据 单价
        String actualPriceSql = Utils.getPrettyNumberSqlString(data.get("actualPrice"), "actualPrice");//获取子表数据 现价


        String taxRateStr = data.get("taxRate") == null ? "0" : data.get("taxRate").toString();//获取子表数据 税率
//        BigDecimal taxRate = "0E-8".equals(taxRateStr) || "0".equals(taxRateStr) ? new BigDecimal("0") : new BigDecimal(taxRateStr).setScale(0, BigDecimal.ROUND_HALF_UP);
        String taxRateString = "0".equals(taxRateStr) ? "is null" : "= '"+new BigDecimal(taxRateStr).setScale(0, BigDecimal.ROUND_HALF_UP)+"'";



        String singleTaxStr = data.get("singleTax") == null ? "0" : data.get("singleTax").toString();//获取子表数据 单税
        BigDecimal singleTax = "0E-8".equals(singleTaxStr) ? new BigDecimal("0") : new BigDecimal(singleTaxStr).setScale(6, BigDecimal.ROUND_HALF_UP);

        String manufactureTxt = MapUtils.getString(data,"manufacture","");//获取子表数据 制造单位
        String manufacture = StringUtils.isBlank(manufactureTxt) ? "is null" : "= '"+manufactureTxt+"'";
        Date deadline = (Date) data.get("deadline");//获取子表数据 //获取子表数据 保修截止期
        String deadlineString = ObjectUtils.isEmpty(deadline) ? "is null" : "= '"+deadline.toString()+"'";

        String warrantyBillTxt = MapUtils.getString(data,"warrantyBillTXT","");//获取子表数据 保修单
        String warrantyBill = StringUtils.isBlank(warrantyBillTxt) ? "is null" : "= '"+warrantyBillTxt+"'";


        StringBuilder sql = new StringBuilder("select *  from ").append(tableName)
                .append(" where companyCode='").append(companyNumber).append("'")
//                .append(" and Supplier ").append(supplierCode)
                .append(" and supplierName ").append(supplierName)
//                .append(" and currency='").append(currencyHidden).append("'")
//                .append(" and currencyRate='").append(exchangeRate).append("'")
                .append(" and warehouseCode='").append(warehouseNumberHidden).append("'")
                .append(" and  ").append(abstractT)
                .append(" and storageSpace ").append(storageSpace)
                .append(" and code='").append(code).append("'")
                .append(" and  ").append(model)
//                .append(" and  replace(replace(ifnull(model,''）,'/','') ,'\\\\','')  = replace(replace( ").append(model).append(" ,'/','') ,'\\\\','') " )
                .append(" and batch ").append(batch)
                .append(" and productionDate ").append(productionDateString)
                .append(" and expiryDate ").append(expiryDateString)
                .append(" and measuringUnit='").append(measuringUnit).append("'")
                .append(" and auxiliaryUnit ").append(auxiliaryUnit)
                .append(" and ").append(priceSql)
                .append(" and ").append(actualPriceSql)
                .append(" and taxRate ").append(taxRateString).append("")
//                .append(" and singleTax='").append(singleTax).append("'")
                .append(" and manufacture ").append(manufacture)
                .append(" and deadline ").append(deadlineString)
                .append(" and WarrantyBill ").append(warrantyBill);

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return map;
    }

    /**
     * 转换成  库存 的数据
     *
     * @param map
     * @param auditDate
     * @param bizObject
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String auditer, BizObjectCreatedModel bizObject) {
        Map<String, Object> data = new HashMap<>();
        //TODO: 将子表数据放到data中，后续作为新增基础表的数据使用，待补充


        Map<String, Object> company = (Map<String, Object>) bizObject.get("company");
        String companyId = (String) company.get("id");
        //公司id
        data.put("company", companyId);
        //公司代码
        data.put("companyCode", bizObject.get("companyNumber"));
        //公司名称
        data.put("companyName", bizObject.get("companyName"));

        Map<String, Object> warehouse = (Map<String, Object>) bizObject.get("warehouseNumber");
        String warehouseId = (String) warehouse.get("id");
        //仓库id
        data.put("warehouse", warehouseId);
        //仓库代码
        data.put("warehouseCode", bizObject.get("warehouseNumberHidden"));
        //仓库名称
        data.put("wasrhouse", bizObject.get("warehouseName"));

        //仓位
        data.put("storageSpace", map.get("storageSpace"));


        //物料id
        data.put("material", map.get("matCode"));
        //物料代码
        data.put("Code", map.get("code"));
        //物料名称
        data.put("materialName", map.get("materialName"));

        //型号示例
        data.put("modelExample", map.get("modelExample"));
        //型号
        data.put("model", map.get("model"));
        //摘要
        data.put("abstract", map.get("abstract"));

        //币别
        data.put("currency", bizObject.get("currencyHidden"));
        //汇率
        data.put("currencyRate", bizObject.get("exchangeRate"));

        //批次
        data.put("batch", map.get("batch"));
        //生产日期
        data.put("productionDate", map.get("productionDate"));
        //到期日期
        data.put("expiryDate", map.get("expiryDate"));

        //计量单位
        data.put("measuringUnit", map.get("measuringUnit"));
        //数量
        data.put("quantity", map.get("quantity"));
        //辅助计量单位
        data.put("auxiliaryUnit", map.get("auxiliaryUnit"));
        //辅助数量
        data.put("auxiliaryQuantity", map.get("auxiliaryQuantity"));

        //单价
        data.put("price", map.get("unitPrice"));
        //现价
        data.put("actualPrice", map.get("actualPrice"));
        //税率
        data.put("taxRate", map.get("taxRate"));

        //金额
        data.put("amount", map.get("amount"));
        //现值
        data.put("actualAmount", map.get("actualAmount"));
        //税额
        data.put("tax", map.get("tax"));

        //单税
        data.put("singleTax", map.get("singleTax"));
        //含税单价
        data.put("priceInclTax", map.get("priceInclTax"));
        //价税合计
        data.put("total", map.get("total"));

        //制造单位
        data.put("manufacture", map.get("manufacture"));
        //保修截止期
        data.put("deadline", map.get("deadline"));
        //保修单
        data.put("WarrantyBill", map.get("warrantyBillTXT"));


        return data;
    }

    /**
     * 转换成  預库存 的数据
     *
     * @param map
     * @param auditDate
     * @param bizObject
     * @return
     */
    private Map<String, Object> fileInfoPreBaseMap(Map<String, Object> map, String auditDate, String auditer, BizObjectCreatedModel bizObject) {
        Map<String, Object> data = new HashMap<>();

        data.put("entryDate", map.get("entryDate"));
        data.put("type", bizObject.get("type"));


        //公司id
        data.put("company", bizObject.get("company"));
        //公司代码
        data.put("companyCode", bizObject.get("companyNumber"));
        //公司名称
        data.put("companyName", bizObject.get("companyName"));


        //仓库id
        data.put("warehouseGuanlian", bizObject.get("warehouseNumber"));
        //仓库代码
        data.put("warehouseCode", bizObject.get("warehouseNumberHidden"));
        //仓库名称
        data.put("wasrhouse", bizObject.get("warehouseName"));

        //仓位
        data.put("storageSpace", map.get("storageSpace"));


        //物料id
        data.put("naterialGuanlian", map.get("matCode"));
        //物料代码
        data.put("Code", map.get("code"));
        //物料名称
        data.put("ykcName", map.get("materialName"));

        //型号示例
        data.put("modelExample", map.get("modelExample"));
        //型号
        data.put("model", map.get("model"));
        //摘要
        data.put("abstract", map.get("abstract"));

        //币别
        data.put("currency", bizObject.get("currencyHidden"));
        //汇率
        data.put("currencyRate", bizObject.get("exchangeRate"));

        //批次
        data.put("batch", map.get("batch"));
        //生产日期
        data.put("productionDate", map.get("productionDate"));
        //到期日期
        data.put("expiryDate", map.get("expiryDate"));

        //计量单位
        data.put("measuringUnit", map.get("measuringUnit"));
        //数量
        data.put("quantity", map.get("quantity"));
        //辅助计量单位
        data.put("auxiliaryUnit", map.get("auxiliaryUnit"));
        //辅助数量
        data.put("auxiliaryQuantity", map.get("auxiliaryQuantity"));

        //单价
        data.put("price", map.get("unitPrice"));
        //现价
        data.put("actualPrice", map.get("actualPrice"));
        //税率
        data.put("taxRate", map.get("taxRate"));

        //金额
        data.put("amount", map.get("amount"));
        //现值
        data.put("Number1669436810003", map.get("actualAmount"));
        //税额
        data.put("tax", map.get("tax"));

        //单税
        data.put("singleTax", map.get("singleTax"));
        //含税单价
        data.put("priceInclTax", map.get("priceInclTax"));
        //价税合计
        data.put("total", map.get("total"));

        //制造单位
        data.put("manufacture", map.get("manufacture"));
        //保修截止期
        data.put("deadline", map.get("deadline"));
        //保修单
        data.put("WarrantyBill", map.get("warrantyBillTXT"));


        return data;
    }
}



